﻿#ifndef __SS_DICTIONARY_H__
#define __SS_DICTIONARY_H__
#include "trieTree/ssTrieTree.h"


namespace StarSeeker
{

template<typename D_KEY, typename D_VALUE>
class ssDictionary
{
public:
	class Iterator
	{
		friend class ssDictionary;
	public:
		Iterator() :m_pNode(0)
		{
		}
		Iterator(const Iterator & it) :m_pNode(it.m_pNode)
		{
		}
		Iterator(ssTrieNode<D_KEY, D_VALUE>* p) :m_pNode(p)
		{
		}
		bool operator == (const Iterator& it) const
		{
			return this->m_pNode == it.m_pNode;
		}
		bool operator != (const Iterator& it) const
		{
			return this->m_pNode != it.m_pNode;
		}
		void operator = (const Iterator& it)
		{
			this->m_pNode = it.m_pNode;
		}
		const D_KEY& Key()
		{
			return m_pNode->Key();
		}
		D_VALUE* Data()
		{
			return m_pNode->Data();
		}
		bool IsVaild() const
		{
			if (!m_pNode)
			{
				return false;
			}
			if (0 == m_pNode->Onwer())
			{
				return false;
			}
			return true;
		}
	private:
		ssTrieNode<D_KEY, D_VALUE>*	m_pNode;
	};

	ssPair<Iterator, error_t>	Insert(const D_KEY* arr, size_t len, D_VALUE* val);
	ssPair<Iterator, error_t>	InsertCover(const D_KEY* arr, size_t len, D_VALUE* val);
	Iterator		Find(const D_KEY* arr, size_t len);
	error_t			Erase(Iterator& itr);
	error_t			Erase(const D_KEY* arr, size_t len);
	void			Empty();
	ulint			Size();
private:
	ssTrieTree<D_KEY, D_VALUE>		m_tree;
};

template<typename D_KEY, typename D_VALUE>
inline ssPair<typename ssDictionary<D_KEY, D_VALUE>::Iterator, error_t> ssDictionary<D_KEY, D_VALUE>::Insert(const D_KEY * arr, size_t len, D_VALUE * val)
{
	ssPair<ssTrieNode<D_KEY, D_VALUE>*, error_t> ret = m_tree.Insert(arr, len, val);
	return ssPair<typename ssDictionary<D_KEY, D_VALUE>::Iterator, error_t>(ret.first, ret.second);
}

template<typename D_KEY, typename D_VALUE>
inline ssPair<typename ssDictionary<D_KEY, D_VALUE>::Iterator, error_t> ssDictionary<D_KEY, D_VALUE>::InsertCover(const D_KEY * arr, size_t len, D_VALUE * val)
{
	ssPair<ssTrieNode<D_KEY, D_VALUE>*, error_t> ret = m_tree.Insert(arr, len, val);
	if (ret.second==SS_DICT_KEY_EXISTED)
	{
		ret.first.SetData(val);
	}
	return ssPair<typename ssDictionary<D_KEY, D_VALUE>::Iterator, error_t>(ret.first, ret.second);
}

template<typename D_KEY, typename D_VALUE>
inline typename ssDictionary<D_KEY, D_VALUE>::Iterator ssDictionary<D_KEY, D_VALUE>::Find(const D_KEY * arr, size_t len)
{
	return m_tree.Find(arr, len);
}

template<typename D_KEY, typename D_VALUE>
inline error_t ssDictionary<D_KEY, D_VALUE>::Erase(Iterator & itr)
{
	error_t ret = m_tree.Remove(itr.m_pNode);
	if (ret == SS_DICT_OK)
	{
		itr.m_pNode = 0;
	}
	return ret;
}

template<typename D_KEY, typename D_VALUE>
inline error_t ssDictionary<D_KEY, D_VALUE>::Erase(const D_KEY * arr, size_t len)
{
	return m_tree.Remove(arr, len);
}

template<typename D_KEY, typename D_VALUE>
inline void ssDictionary<D_KEY, D_VALUE>::Empty()
{
	m_tree.Empty();
}

template<typename D_KEY, typename D_VALUE>
inline ulint ssDictionary<D_KEY, D_VALUE>::Size()
{
	return m_tree.GetCount();
}

}
#endif
